from crowd_sim.envs.utils.agent import Agent
from crowd_sim.envs.utils.state import JointState
import logging


class Human(Agent):
    def __init__(self, config, section):
        super().__init__(config, section)
        self.id = None

    def act(self, ob):
        """
        The state for human is its full state and all other agents' observable states
        :param ob:
        :return:
        """
        state = JointState(self.get_full_state(), ob)
        action = self.policy.predict(state)
        return action


class Data_human(Agent):  # 还是需要把轨迹转化为速度，因为需要被机器人观测到他的速度
    def __init__(self, config, section, id):
        """
            A new class for human, whose trajectories are from dataset.
        """
        super().__init__(config, section)
        self.id = id
        self.trajectories = None

    def set_trajectories(self, trajectories):
        self.trajectories = trajectories

    def get_trajectories(self):
        return self.trajectories

    def act(self, ob):
        """
         I have replaced predict with read_data. But in the base class: Policy, predict is a abstract method.
        So I have to do this, but this function can not be called.
        """
        logging.warning("The act function in Data_human policy should not be called")
        return ob

    def act_from_trajectories(self): # dict of dict of tuple: { frame_id: {pedestrian_id:(x,y), ......
        action = self.policy.read_data(self.id, self.trajectories)
        self.trajectories.pop(0)
        return action





